package com.qdc.datacenters.listener;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.qdc.datacenters.config.SystemConfig;
import com.qdc.datacenters.constant.ChatMsgConstants;
import com.qdc.datacenters.domain.entity.ChatContactMsgAttachment;
import com.qdc.datacenters.domain.entity.SysCorp;
import com.qdc.datacenters.domain.media.*;
import com.qdc.datacenters.domain.query.corp.SysCorpQuery;
import com.qdc.datacenters.domain.queue.ChatMsgMediaQueue;
import com.qdc.datacenters.event.QwMediaPullEvent;
import com.qdc.datacenters.service.IChatContactMsgService;
import com.qdc.datacenters.service.ISysCorpService;
import com.qdc.datacenters.service.impl.ThreadFactoryImpl;
import com.qdc.datacenters.utils.ThreadUtils;
import com.tencent.wework.FinanceService;
import jakarta.annotation.PreDestroy;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

/**
 * @author danmo
 * @date 2024-03-12 15:04
 **/
@Slf4j
@AllArgsConstructor
@Component
public class QwMediaPullListener implements ApplicationListener<QwMediaPullEvent> {

    private final ThreadPoolExecutor mediaPullExecutor = new ThreadPoolExecutor(5, 10, 10L, MILLISECONDS, new ArrayBlockingQueue<>(1024), new ThreadFactoryImpl("mediaPullThread_"));

    private final IChatContactMsgService iChatContactMsgService;
    private final SystemConfig systemConfig;
    private final ISysCorpService iSysCorpService;
    private final ApplicationContext applicationContext;

    @Override
    public void onApplicationEvent(QwMediaPullEvent event) {
        mediaPullExecutor.execute(() -> {

            ChatMsgMediaQueue msgMediaQueue = (ChatMsgMediaQueue) event.getSource();
            if (Objects.nonNull(msgMediaQueue)) {
                ChatContactMsgAttachment attachment = new ChatContactMsgAttachment();
                attachment.setMsgId(msgMediaQueue.getMsgId());
                attachment.setStatus(2);
                try {
                    if (StringUtils.equals("image", msgMediaQueue.getMediaType())) {
                        QwImage qwImage = JSONObject.parseObject(msgMediaQueue.getMediaInfo(), QwImage.class);
                        String fileName = qwImage.getMd5sum() + ".jpg";
                        String mediaFile = pullMediaFile(qwImage.getMd5sum(), qwImage.getSdkFileId(), fileName, msgMediaQueue.getMediaType());
                        if (StringUtils.isEmpty(mediaFile)) {
                            attachment.setStatus(-1);
                        }
                        attachment.setFileName(fileName);
                        attachment.setMd5(qwImage.getMd5sum());
                        attachment.setFilePath(mediaFile);
                        attachment.setFileSize(qwImage.getFileSize());
                        attachment.setSdkFileId(qwImage.getSdkFileId());
                    } else if (StringUtils.equals("voice", msgMediaQueue.getMediaType())) {
                        QwVoice qwVoice = JSONObject.parseObject(msgMediaQueue.getMediaInfo(), QwVoice.class);
                        String fileName = qwVoice.getMd5sum() + ".amr";
                        String mediaFile = pullMediaFile(qwVoice.getMd5sum(), qwVoice.getSdkFileId(), fileName, msgMediaQueue.getMediaType());
                        if (StringUtils.isEmpty(mediaFile)) {
                            attachment.setStatus(-1);
                        }
                        attachment.setFileName(fileName);
                        attachment.setMd5(qwVoice.getMd5sum());
                        attachment.setFilePath(mediaFile);
                        attachment.setFileSize(qwVoice.getVoiceSize());
                        attachment.setSdkFileId(qwVoice.getSdkFileId());
                        attachment.setPlayLength(qwVoice.getPlayLength());
                    } else if (StringUtils.equals("video", msgMediaQueue.getMediaType())) {
                        QwVideo qwVideo = JSONObject.parseObject(msgMediaQueue.getMediaInfo(), QwVideo.class);
                        String fileName = qwVideo.getMd5sum() + ".mp4";
                        String mediaFile = pullMediaFile(qwVideo.getMd5sum(), qwVideo.getSdkFileId(), fileName, msgMediaQueue.getMediaType());
                        if (StringUtils.isEmpty(mediaFile)) {
                            attachment.setStatus(-1);
                        }
                        attachment.setFileName(fileName);
                        attachment.setMd5(qwVideo.getMd5sum());
                        attachment.setFilePath(mediaFile);
                        attachment.setFileSize(qwVideo.getFileSize());
                        attachment.setSdkFileId(qwVideo.getSdkFileId());
                    } else if (StringUtils.equals("emotion", msgMediaQueue.getMediaType())) {
                        QwEmotion qwEmotion = JSONObject.parseObject(msgMediaQueue.getMediaInfo(), QwEmotion.class);
                        String fileName = "";
                        switch (qwEmotion.getType()) {
                            case 1 -> fileName = qwEmotion.getMd5sum() + ".gif";
                            case 2 -> fileName = qwEmotion.getMd5sum() + ".png";
                        }
                        String mediaFile = pullMediaFile(qwEmotion.getMd5sum(), qwEmotion.getSdkFileId(), fileName, msgMediaQueue.getMediaType());
                        if (StringUtils.isEmpty(mediaFile)) {
                            attachment.setStatus(-1);
                        }
                        attachment.setFileName(fileName);
                        attachment.setMd5(qwEmotion.getMd5sum());
                        attachment.setHeight(qwEmotion.getHeight());
                        attachment.setWidth(qwEmotion.getWidth());
                        attachment.setFilePath(mediaFile);
                        attachment.setFileSize(qwEmotion.getImageSize());
                        attachment.setSdkFileId(qwEmotion.getSdkFileId());
                    } else if (StringUtils.equals("file", msgMediaQueue.getMediaType())) {
                        QwFile qwFile = JSONObject.parseObject(msgMediaQueue.getMediaInfo(), QwFile.class);
                        String fileName = qwFile.getFileName() + "." + qwFile.getFileExt();
                        String mediaFile = pullMediaFile(qwFile.getMd5sum(), qwFile.getSdkFileId(), fileName, msgMediaQueue.getMediaType());
                        if (StringUtils.isEmpty(mediaFile)) {
                            attachment.setStatus(-1);
                        }
                        attachment.setFileName(fileName);
                        attachment.setMd5(qwFile.getMd5sum());
                        attachment.setFilePath(mediaFile);
                        attachment.setFileSize(qwFile.getFileSize());
                        attachment.setSdkFileId(qwFile.getSdkFileId());
                    } else if (StringUtils.equals("mixed", msgMediaQueue.getMediaType())) {
                        QwMixed qwMixed = JSONObject.parseObject(msgMediaQueue.getMediaInfo(), QwMixed.class);
                        for (JSONObject item : qwMixed.getItem()) {
                            pushMediaQueue(msgMediaQueue.getMsgId(), item.getString("type"), item.getString("content"));
                        }
                    }
                } catch (Exception e) {
                    log.error("media attachment consume msgId:{}, error:{}", msgMediaQueue.getMsgId(), e.getMessage(), e);
                    attachment.setStatus(-1);
                    attachment.setErrorMsg(e.getMessage());
                }
                iChatContactMsgService.saveAttachment(attachment);
            }
        });
    }

    private synchronized String pullMediaFile(String md5, String sdkFileId, String fileName, String mediaType) {
        SysCorp sysCorp = iSysCorpService.get(new SysCorpQuery());
        if (Objects.isNull(sysCorp)
                || StringUtils.isEmpty(sysCorp.getCorpId())
                || StringUtils.isEmpty(sysCorp.getChatSecret())
                || StringUtils.isEmpty(sysCorp.getEncodingAesKey())) {
            return "";
        }
        FinanceService financeService = new FinanceService(sysCorp.getCorpId(), sysCorp.getChatSecret(), null);
        ChatContactMsgAttachment msgAttachment = iChatContactMsgService.getAttachmentByMd5(md5);
        if (Objects.nonNull(msgAttachment)) {
            return msgAttachment.getFilePath();
        }
        String file = systemConfig.getDownPath() + File.separator
                + DateUtil.formatDate(new Date()) + File.separator
                + mediaType + File.separator
                + fileName;

        if (!financeService.getMediaData(sdkFileId, file)) {
            return "";
        }
        return systemConfig.getAddress() + file;
    }

    protected void pushMediaQueue(Long msgId, String mstType, String content) {
        switch (mstType) {
            case "image", "voice", "video", "emotion", "file", "mixed" ->
                    applicationContext.publishEvent(new QwMediaPullEvent(ChatMsgMediaQueue.builder()
                            .msgId(msgId)
                            .mediaType(mstType)
                            .mediaInfo(content).build()));
        }
    }

    @PreDestroy
    public  void shutdown(){
        log.info("会话存档素材拉取线程池开始注销");
        ThreadUtils.shutdownAndAwaitTermination(mediaPullExecutor);
    }
}
